package edu.stanford.hardon.Tabs;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ToggleButton;
import edu.stanford.hardon.DatabaseHelper;
import edu.stanford.hardon.R;
import edu.stanford.hardon.TravelCore;
import edu.stanford.hardon.TravelHarder;
import edu.stanford.hardon.TravelHardConstants;
import edu.stanford.hardon.Capture.AudioRecorder;
import edu.stanford.hardon.Media.Media;
import edu.stanford.hardon.Media.MediaType;
import edu.stanford.hardon.Media.RichMedia;

public class CameraTab extends GenericTab {

	//Camera specific variables
	private SurfaceView preview = null;
	private SurfaceHolder previewHolder=null;
	private Camera camera = null;
	private boolean usingCamera = false;
	private boolean inPreview = false;
	private int currentFreeFile;
	//private boolean annotateView = false;
	private Media currentMedia;
	private MediaTabState state = MediaTabState.MAIN;
	private RelativeLayout mainView;
	private RelativeLayout photoView;
	private RelativeLayout audioView;
	private AudioRecorder recorder;


	
	public CameraTab(int Id, String Text, int iconResourceId, final LinearLayout tabLayout, SurfaceView previewSurface, TravelHarder th) {
		super(Id, Text, iconResourceId,tabLayout, th);

		//set up tab to contain a camera view thingy.
		currentFreeFile = 0;
        preview = previewSurface;
    	LayoutParams lp = preview.getLayoutParams();

    	
    	mainView = (RelativeLayout) tabLayout.findViewById(R.id.camera_view);
    	photoView = (RelativeLayout) tabLayout.findViewById(R.id.annotator);
    	//audioView = (RelativeLayout) tabLayout.findViewById(R.id.audio_annotation);
		
		preview.setLayoutParams(lp);
        previewHolder = preview.getHolder();
		previewHolder.addCallback(surfaceCallback);
		previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		ImageButton captureButton = (ImageButton) tabLayout.findViewById(R.id.capture_image);
		captureButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	camera.takePicture(null, null, photoCallback);
            }
        });
	
		/*
		ImageButton addAudioButton = (ImageButton) tabLayout.findViewById(R.id.add_audio);
		addAudioButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	switchState(MediaTabState.AUDIO_VIEW, currentMedia);
            }
        });
		*/
		
		ImageButton deletePhotoButton = (ImageButton) tabLayout.findViewById(R.id.delete_photo);
		deletePhotoButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
				DatabaseHelper dbhh = TravelCore.getDBH();
				dbhh.open();
				dbhh.deleteMedia(currentMedia.getDBID());
				dbhh.close();
				onBackButtonDown();
            }
        });
		
		/*
		final ToggleButton recordAudioButton =  (ToggleButton) tabLayout.findViewById(R.id.record_audio_annotation);
		recordAudioButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	try {
    				if (recordAudioButton.isChecked()) {
    			        recorder = new AudioRecorder();
    					recorder.record();
    				} else {
    					recorder.stopRecording();
    					saveAudioToDB();
    					onBackButtonDown();
    				}
//    				if(!recording){
//    					recording = true;
//    					recorder.record();
//    				} else {
//    					recording = false;
//    					recorder.stopRecording();
//    				}
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
            }
        });
        */
		
	}

	public void switchState(MediaTabState newState, Media m){
		state = newState;
		currentMedia = m;
		updateState();
		//stopTab();
	}
	
	private void updateState(){
		switch(state){
		case MAIN:{
			mainView.setVisibility(View.VISIBLE);
			photoView.setVisibility(View.GONE);
			audioView.setVisibility(View.GONE);
			startTab();
			break;
		}
		case PHOTO_VIEW:{
			mainView.setVisibility(View.GONE);
			photoView.setVisibility(View.VISIBLE);
			audioView.setVisibility(View.GONE);
			break;
		}
		case AUDIO_VIEW:{
			mainView.setVisibility(View.GONE);
			photoView.setVisibility(View.GONE);
			audioView.setVisibility(View.VISIBLE);
			break;
		}
		case NOTE_VIEW:{
			mainView.setVisibility(View.GONE);
			photoView.setVisibility(View.GONE);
			audioView.setVisibility(View.GONE);
			break;
		}
		default:{
			mainView.setVisibility(View.VISIBLE);
			photoView.setVisibility(View.GONE);
			audioView.setVisibility(View.GONE);
			startTab();
			break;
		}
		}

	}

	public void startTab() {
		if(camera == null){
			camera = Camera.open();
			//camera.setParameters(camera.getParameters());
			try{
				camera.setPreviewDisplay(previewHolder);
				camera.setDisplayOrientation(90);
				Camera.Parameters params = camera.getParameters();
				List<String> flashModes = params.getSupportedFlashModes();
				if(flashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)){
					params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
				}
				camera.setParameters(params);
			}
			catch(IOException e){
				
			}
			
		}
		
		camera.startPreview();
		usingCamera = true;
		inPreview = true;
		
	}

	public void stopTab() {
		// TODO Auto-generated method stub
		if(camera != null){
			camera.stopPreview();
			camera.release();
			camera=null;
			inPreview=false;
			usingCamera = false;
		}
	}
	
	  
    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
		public void surfaceCreated(SurfaceHolder holder) {
			if (usingCamera) {
				try {
					camera.setPreviewDisplay(previewHolder);
					camera.setDisplayOrientation(90);
					
					if (!inPreview) {

						camera.startPreview();
						inPreview = true;
					}
				} catch (Throwable t) {
					// Log.e("PictureDemo-surfaceCallback",
					// "Exception in setPreviewDisplay()", t);
					// Toast
					// .makeText(TravelHard.this, t.getMessage(),
					// Toast.LENGTH_LONG)
					// .show();
				}
			}
		}
		
		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
			if (camera != null && usingCamera) {
				if (!inPreview) {
					Camera.Parameters parameters = camera.getParameters();

					parameters.setPreviewSize(width, height);
					parameters.setPictureFormat(PixelFormat.JPEG);

					camera.setParameters(parameters);

					camera.startPreview();
					inPreview = true;
				}
			}
		}
		
		public void surfaceDestroyed(SurfaceHolder holder) {
			// no-op
		}
	};

	public void setPaused() {
		if(usingCamera){
			if (inPreview) {
				camera.stopPreview();
			}
		
			camera.release();
			camera = null;
			inPreview = false;
			usingCamera = false;
		}
	}

	public void setResumed() {
		if (camera == null) {
			camera = Camera.open();
			camera.setParameters(camera.getParameters());
			try {
				camera.setPreviewDisplay(previewHolder);
				camera.setDisplayOrientation(90);
			} catch (IOException e) {

			}
			camera.startPreview();
			usingCamera = true;
			inPreview = true;

		}
	}
	
	
	private void saveAudioToDB(){
		//final String date = getTimeNow();
		Date date = new Date();
		Double lat = 0.0, lng = 0.0, alt = 0.0;
		if(th.location != null){
			lat = th.location.getLatitude();
			lng = th.location.getLongitude();
			alt = th.location.getAltitude();
		}
		RichMedia audioMedia = new RichMedia(null, TravelHardConstants.TRIP_ID, MediaType.AUDIO, lat, lng, alt, date, null, currentMedia.getDBID(), recorder.getAudioFile().getPath());

		DatabaseHelper dbhh = TravelCore.getDBH();
		dbhh.open();
		dbhh.insert(audioMedia);
		dbhh.close();
	}
	
	Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
		public void onPictureTaken(byte[] data, Camera camera) {
			
			File photo = null;
			
			while (photo == null || photo.exists()) {
				photo = new File(Environment.getExternalStorageDirectory(), "photo" + currentFreeFile + ".jpg");
				currentFreeFile++;
			}
			
			new SavePhotoTask(photo).execute(data);
			//camera.startPreview();
			//inPreview = true;
		}
	};
	
	class SavePhotoTask extends AsyncTask<byte[], String, String> {
		
		private File photo;
		
		public SavePhotoTask(File photo){
			this.photo = photo;
		}
		
		protected String doInBackground(byte[]... jpeg) {
			
			Log.i("PHOTO", photo.getPath());
			
			try {
				if(photo != null){
					FileOutputStream fos = new FileOutputStream(photo.getPath());
					fos.write(jpeg[0]);
					fos.close();
					
					// create Photo object
					//final String date = getTimeNow();
			        Date date = new Date();
					Double lat = 0.0, lng = 0.0, alt = 0.0;
					if(th.location != null) {
						lat = th.location.getLatitude();
						lng = th.location.getLongitude();
						alt = th.location.getAltitude();
					}					
					RichMedia photoMedia = new RichMedia(null, TravelHardConstants.TRIP_ID, MediaType.PHOTO, lat, lng, alt, date, null, null, photo.getPath());
					currentMedia = photoMedia;
					
					DatabaseHelper dbhh = TravelCore.getDBH();
					dbhh.open();
					long mediaId = dbhh.insert(photoMedia);
					currentMedia.setDBID(mediaId);
					dbhh.close();					
				}
			}
			catch (java.io.IOException e) {
				Log.e("PictureDemo", "Exception in photoCallback", e);
			}

			
			return(photo.toString());
		}
		
		protected void onPostExecute(String photoToString){
			BitmapFactory.Options opts = new BitmapFactory.Options();
			Bitmap b = BitmapFactory.decodeFile(photo.toString(), opts);
        	//ImageView toAnnotate = (ImageView)tabLayout.findViewById(R.id.to_annotate);
        	//toAnnotate.setImageBitmap(Bitmap.createScaledBitmap(b, 480, 320, true));
        	//ImageView audioAnnotatePhoto = (ImageView)tabLayout.findViewById(R.id.audio_annotate_photo);
        	//audioAnnotatePhoto.setImageBitmap(Bitmap.createScaledBitmap(b, 480, 320, true));
        	switchState(MediaTabState.PHOTO_VIEW, currentMedia);
			b.recycle();
		}
	}
	
	@Override
	public boolean onBackButtonDown(){
		boolean valid = true;
		
		switch(state){
		case MAIN:{
			valid = false;
			break;
		}
		case PHOTO_VIEW:{
			switchState(MediaTabState.MAIN, currentMedia);
			break;
		}
		case AUDIO_VIEW:{
			switchState(MediaTabState.PHOTO_VIEW, currentMedia);
			break;
		}
		case NOTE_VIEW:{
			switchState(MediaTabState.PHOTO_VIEW, currentMedia);
			break;
		}
		default:{
			valid = false;
			break;
		}
		}

		return valid;
	}

}
